home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 6 / CU Amiga Magazine's Super CD-ROM 06 (1996)(EMAP Images)(GB)(Track 1 of 4)[!][issue 1997-01].iso / cucd / magazine / executive_v2.00 / data / developers.lzx / SysInfo / examples / uptime / uptime.c < prev   
C/C++ Source or Header  |  2002-04-16  |  7KB  |  335 lines

  1. /*
  2.  * Uptime
  3.  *
  4.  * This file is public domain.
  5.  *
  6.  * Author: Petri Nordlund <petrin@megabaud.fi>
  7.  *
  8.  * $Id: uptime.c 1.7 1996/10/01 23:04:41 petrin Exp petrin $
  9.  *
  10.  */
  11.  
  12. /*
  13.  * This is a fairly complete uptime-program. The sourcecode comes from
  14.  * Executive uptime-client, it's just modified to support SysInfo.library.
  15.  * This program can be compiled for multiuser.library support to show the
  16.  * number of users currently logged in. This requires multiuser.library
  17.  * include-files and a stub-library if you are using GCC. See
  18.  * GCC:geninline/README.glue for information about how to generate
  19.  * the stub-library.
  20.  *
  21.  */
  22.  
  23. #include "defs.h"
  24. #include <proto/SysInfo.h>
  25. #include <libraries/SysInfo.h>
  26.  
  27.  
  28. /* PROTOTYPES */
  29. #ifdef USE_MULTIUSER
  30. static void AddUser(ULONG user, UWORD *uids, ULONG *nusers);
  31. static ULONG CountTasks(void);
  32. #endif /* USE_MULTIUSER */
  33. static void MyExit(void);
  34. static void GetTime(void);
  35. static void Users(void);
  36. static void LoadAverages(void);
  37. static void Uptime(void);
  38.  
  39.  
  40. /* EXTERNAL VARIABLES */
  41. extern struct ExecBase *SysBase;
  42.  
  43.  
  44. /* VARIABLES */
  45. #ifdef USE_MULTIUSER
  46. struct muBase *muBase = NULL;
  47. #endif /* USE_MULTIUSER */
  48. struct SysInfo *si = NULL;
  49. struct Library *SysInfoBase = NULL;
  50.  
  51.  
  52. int
  53. main(int argc, char **argv)
  54. {
  55.     /* MyExit will be called when we exit */
  56.     atexit(MyExit);
  57.  
  58.     if(!(SysInfoBase = OpenLibrary(SYSINFONAME, SYSINFOVERSION)))
  59.     {
  60.         puts("Can't open SysInfo.library.");
  61.         exit(RETURN_FAIL);
  62.     }
  63.  
  64.     /* Initialize SysInfo.library, this will make the connection to the
  65.      * server-process and allocate the SysInfo-structure. */
  66.     if(!(si = InitSysInfo()))
  67.     {
  68.         puts("Can't initialize SysInfo.");
  69.         exit(RETURN_FAIL);
  70.     }
  71.  
  72. #ifdef USE_MULTIUSER
  73.     /* If this fails, we'll just output "1 user" */
  74.     muBase = (struct muBase *) OpenLibrary(MULTIUSERNAME,MULTIUSERVERSION);
  75. #endif /* USE_MULTIUSER */
  76.  
  77.     GetTime();
  78.     printf(", ");
  79.     Uptime();
  80.     printf(", ");
  81.     Users();
  82.     printf(", ");
  83.     LoadAverages();
  84.     printf("\n");
  85.  
  86.     return(RETURN_OK);
  87. }
  88.  
  89.  
  90. /*
  91.  * Exit. Free everything.
  92.  */
  93. static void
  94. MyExit(void)
  95. {
  96. #ifdef USE_MULTIUSER
  97.     if(muBase)
  98.         CloseLibrary((struct Library *) muBase);
  99. #endif /* USE_MULTIUSER */
  100.  
  101.     /* Free SysInfo.library */
  102.     if(si)
  103.         FreeSysInfo(si);
  104.  
  105.     if(SysInfoBase)
  106.         CloseLibrary(SysInfoBase);
  107. }
  108.  
  109.  
  110. /*
  111.  * Print system time
  112.  */
  113. static void
  114. GetTime(void)
  115. {
  116.     struct DateTime dtime;
  117.     char timestr[LEN_DATSTRING+1];
  118.  
  119.     DateStamp(&dtime.dat_Stamp);
  120.  
  121.     dtime.dat_Format = FORMAT_DOS;
  122.     dtime.dat_Flags = 0;
  123.     dtime.dat_StrDay = NULL;
  124.     dtime.dat_StrDate = NULL;
  125.     dtime.dat_StrTime = timestr;
  126.  
  127.     DateToStr(&dtime);
  128.  
  129.     printf(timestr);
  130. }
  131.  
  132.  
  133. /*
  134.  * Print number of users (from Multiuser if available)
  135.  */
  136. static void
  137. Users(void)
  138. {
  139.     ULONG nusers = 1;
  140.  
  141. #ifdef USE_MULTIUSER
  142.     if(muBase)
  143.     {
  144.         ULONG numtasks;
  145.         UWORD *uids;
  146.  
  147.         Forbid();
  148.  
  149.         /* Count the number of tasks currently in system */
  150.         numtasks = CountTasks();
  151.  
  152.         /* Allocate memory for each task */
  153.         if(uids=AllocVec(numtasks*sizeof(UWORD),MEMF_CLEAR|MEMF_PUBLIC))
  154.         {
  155.             struct Task *task;
  156.  
  157.             /* Find out how many different uids there are */
  158.  
  159.             nusers = 0;
  160.             AddUser(muGetTaskOwner(FindTask(NULL)), uids, &nusers);
  161.             for(task = (struct Task *)SysBase->TaskReady.lh_Head;
  162.                 task->tc_Node.ln_Succ;
  163.                 task = (struct Task *)task->tc_Node.ln_Succ)
  164.                 AddUser(muGetTaskOwner(task), uids, &nusers);
  165.             for(task = (struct Task *)SysBase->TaskWait.lh_Head;
  166.                 task->tc_Node.ln_Succ;
  167.                 task = (struct Task *)task->tc_Node.ln_Succ)
  168.                 AddUser(muGetTaskOwner(task), uids, &nusers);
  169.             FreeVec(uids);
  170.         }
  171.  
  172.         Permit();
  173.     }
  174. #endif /* USE_MULTIUSER */
  175.  
  176.     if((nusers>1) || (nusers==0))
  177.         printf("%d users", nusers);
  178.     else
  179.         printf("%d user",nusers);
  180. }
  181.  
  182.  
  183. #ifdef USE_MULTIUSER
  184. static void
  185. AddUser(ULONG user, UWORD *uids, ULONG *nusers)
  186. {
  187.     UWORD uid;
  188.     BOOL found = FALSE;
  189.     ULONG i;
  190.  
  191.     if(user)
  192.     {
  193.         uid = user>>16;
  194.         for(i=0; !found && (i<*nusers); i++)
  195.             found = (uids[i] == uid);
  196.         if(!found)
  197.             uids[(*nusers)++] = uid;
  198.     }
  199. }
  200.  
  201. static ULONG
  202. CountTasks(void)
  203. {
  204.     ULONG i = 1;
  205.     struct Task *task;
  206.  
  207.     for (task = (struct Task *)SysBase->TaskReady.lh_Head;
  208.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  209.           i++;
  210.     for (task = (struct Task *)SysBase->TaskWait.lh_Head;
  211.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  212.           i++;
  213.     return(i);
  214. }
  215. #endif /* USE_MULTIUSER */
  216.  
  217.  
  218. /*
  219.  * Print uptime. We use RAM:-disk creation time.
  220.  */
  221. static void
  222. Uptime(void)
  223. {
  224.     LONG boottime;
  225.     LONG currenttime;
  226.     struct DateTime dtime;
  227.     BPTR lock;
  228.     struct InfoData *infodata;
  229.     struct DeviceList *ramdevice;
  230.  
  231. /*
  232.  * InfoData-structure must be long word aligned. By allocating it this way,
  233.  * we can make sure it is aligned properly. GCC has a bug in it's aligned-
  234.  * attribute <sigh> so it's not possible to just use: struct InfoData infodata.
  235.  */
  236.  
  237.     if(!(infodata=AllocMem(sizeof(struct InfoData),MEMF_ANY)))
  238.         return;
  239.  
  240.     if(lock = Lock("RAM:", SHARED_LOCK))
  241.     {
  242.         if((Info(lock, infodata)) == DOSTRUE)
  243.         {
  244.             ramdevice = BADDR(infodata->id_VolumeNode);
  245.  
  246.             boottime =  SMult32(ramdevice->dl_VolumeDate.ds_Days, 86400) +
  247.                         SMult32(ramdevice->dl_VolumeDate.ds_Minute, 60) +
  248.                         SDivMod32(ramdevice->dl_VolumeDate.ds_Tick, TICKS_PER_SECOND);
  249.  
  250.             DateStamp(&dtime.dat_Stamp);
  251.  
  252.             currenttime =     SMult32(dtime.dat_Stamp.ds_Days, 86400) +
  253.                             SMult32(dtime.dat_Stamp.ds_Minute, 60) +
  254.                             SDivMod32(dtime.dat_Stamp.ds_Tick, TICKS_PER_SECOND);
  255.  
  256.             currenttime -= boottime;
  257.  
  258.             if(currenttime > 0)
  259.             {
  260.                 ULONG days, hrs, mins, hrs_tmp;
  261.  
  262.                 /* Calculate days, hours and minutes */
  263.                 days = currenttime/86400;
  264.                 hrs_tmp = hrs = currenttime%86400;
  265.                 hrs = hrs/3600;
  266.                 mins = (hrs_tmp%3600) / 60;
  267.  
  268.                 if(days || hrs || mins)
  269.                     printf("up ");
  270.  
  271.                 if(days > 0)
  272.                 {
  273.                     if(days>1)
  274.                         printf("%d days ", days);
  275.                     else
  276.                         printf("%d day ", days);
  277.                 }
  278.                 if(hrs > 0)
  279.                     printf("%d:%02d", hrs, mins);
  280.                 else
  281.                 {
  282.                     if((mins>1) || (mins==0))
  283.                         printf("%d mins", mins);
  284.                     else
  285.                         printf("%d min", mins);
  286.                 }
  287.             }
  288.         }
  289.         UnLock(lock);
  290.     }
  291.  
  292.     FreeMem(infodata, sizeof(struct InfoData));
  293. }
  294.  
  295.  
  296. /*
  297.  * Print load averages
  298.  */
  299. static void
  300. LoadAverages(void)
  301. {
  302.     struct SI_LoadAverage load;    /* This will be filled by GetLoadAverage() */
  303.  
  304.     GetLoadAverage(si, &load);    /* Ask SysInfo.library for current load averages */
  305.  
  306.     printf("load:");
  307.  
  308.     switch(si->loadavg_type)
  309.     {
  310.         case LOADAVG_FIXEDPNT:
  311.  
  312.             /* Convert fixed point values to floating point values */
  313.  
  314.             if(si->loadavg_time1)
  315.                 printf(" %.2f",(float) load.lavg_fixed.load1 / (float) si->fscale);
  316.             else
  317.                 printf(" N/A");
  318.  
  319.             if(si->loadavg_time2)
  320.                 printf(" %.2f",(float) load.lavg_fixed.load2 / (float) si->fscale);
  321.             else
  322.                 printf(" N/A");
  323.  
  324.             if(si->loadavg_time3)
  325.                 printf(" %.2f",(float) load.lavg_fixed.load3 / (float) si->fscale);
  326.             else
  327.                 printf(" N/A");
  328.  
  329.             break;
  330.         default:
  331.             /* Load average type is not supported */
  332.             printf("-");
  333.     }
  334. }
  335.